# -*- coding: UTF-8 -*-
import tkinter as tk
from tkinter import ttk
from Code.Utils.sc_func import Common
from Code.View.sc_global import Global
from Code.View.sc_base import AppBase, TopWinBase
from Code.View.sc_settings import SettingsTop
from Code.View.sc_module import WidgetTip, ColorButton, TitleFrame, ScrollFrame, LabelEntry
from Code.View.Datamation.sc_provide import view_gate

language_data = view_gate.query_language_data


class LoginApp(AppBase):
    """ 登录界面 """

    def __init__(self, app_gate, master):
        self.app_gate = app_gate
        self.master = master
        self.head_image = view_gate.query_photo_image_data('LGN_HEAD')
        self.eye_image = view_gate.query_photo_image_data('LGN_EYE')
        self.count_limit = view_gate.query_login_limit_data()
        self.default_pwd = view_gate.query_default_pwd_data()
        self.sub_login = []

    def init_windows(self):
        def init_frames():
            win_style = {'master': self.master,
                         'width': Global.G_LGN_WIN_WIDTH,
                         'background': Global.G_DEFAULT_COLOR}
            head_win = tk.Frame(height=Global.G_LGN_HEAD_HEIGHT, **win_style)
            body_win = tk.Frame(height=Global.G_LGN_FUNC_HEIGHT, **win_style)
            foot_win = tk.Frame(height=Global.G_LGN_FOOT_HEIGHT, **win_style)
            body_fm = TitleFrame(body_win,
                                 width=Global.G_LGN_WIN_WIDTH,
                                 height=Global.G_LGN_FUNC_HEIGHT,
                                 title=language_data('LOGIN_SERVER'),
                                 center=True,
                                 color=Global.G_DEFAULT_COLOR
                                 ).master()
            head_win.pack(fill='both')
            body_win.pack(fill='both')
            foot_win.pack(fill='both')
            head_win.pack_propagate(0)
            body_win.pack_propagate(0)
            foot_win.pack_propagate(0)
            return head_win, body_fm, foot_win

        def pack_frames():
            def pack_sub_head_win():
                tk.Label(head_fm, image=self.head_image).pack(fill='both')

            def pack_sub_body_win():
                def see_password(turn):
                    for inst in self.sub_login:
                        inst.see_password(turn)

                def add_sublogin():
                    if len(self.sub_login) >= self.count_limit:
                        info = '{}:{}'.format(language_data('SERVER', 'LOGIN', 'LIMIT'), self.count_limit)
                        WidgetTip.info(info)
                        return
                    SubLogin(entry_fm, preference_ip, self.default_pwd, self.sub_login)

                def pack_sub_entry_fm():
                    # 添加第一个登录子版块
                    add_sublogin()

                def pack_sub_btn_fm():
                    btn_style = {'master': sub_btn_fm,
                                 'font': (Global.G_DEFAULT_FONT, 10),
                                 'bd': 0}
                    add_btn = tk.Button(text='✚', command=add_sublogin, **btn_style)
                    add_btn.pack(side='left', padx=20)
                    eye_btn = tk.Button(image=self.eye_image, **btn_style)
                    eye_btn.pack(side='right', padx=20)
                    eye_btn.bind("<Button-1>", lambda event: see_password(True))
                    eye_btn.bind("<ButtonRelease-1>", lambda event: see_password(False))
                    WidgetTip.enter_tips(add_btn, language_data('ADD_LOGIN_BAR'), 10, 15)
                    WidgetTip.enter_tips(eye_btn, language_data('SHOW_PASSWORD'), 10, 15)

                sub_btn_fm = tk.LabelFrame(body_fm, height=20)
                sub_btn_fm.pack(fill='both')
                entry_fm = ScrollFrame(body_fm).master()
                pack_sub_entry_fm()
                pack_sub_btn_fm()

            def pack_sub_foot_win():
                def settings():
                    SettingsTop().show()

                def click_login():
                    def async_login(args=None):
                        self.try_login_handle()
                        try:
                            login_btn.disable(False)
                        except:
                            pass
                    login_btn.disable(True)
                    Common.create_thread(func=async_login)
                # 选项按钮
                set_byn = tk.Button(foot_fm,
                                    text='☰',
                                    font=(Global.G_DEFAULT_FONT, 18),
                                    bd=0,
                                    activebackground=Global.G_DEFAULT_COLOR,
                                    bg=Global.G_DEFAULT_COLOR,
                                    command=settings
                                    )
                set_byn.pack(side='left', padx=50)
                WidgetTip.enter_tips(set_byn, language_data('PREFERENCES'), 10, 15)
                # 一键登录按钮
                login_btn = ColorButton(foot_fm, size=14, width=26,
                                        text=language_data('ONE_CLICK_LOGIN'), command=click_login)
            pack_sub_head_win()
            pack_sub_body_win()
            pack_sub_foot_win()

        self.app_gate.resize(Global.G_LGN_WIN_WIDTH, Global.G_LGN_WIN_HEIGHT)
        preference_ip = view_gate.query_preference_ip_data()
        head_fm, body_fm, foot_fm = init_frames()
        pack_frames()

    def try_login_handle(self):
        """ 一键登录逻辑处理 """
        def check_input():
            if not all(input_list):
                WidgetTip.error(language_data('INPUT', 'CANT_NULL'))
                return False
            ip, user, upwd, rpwd = input_list
            if not Common.is_ip(ip):
                WidgetTip.error('IP {}'.format(language_data('INVALID_PARAMETERS')))
                return False
            if ip in ip_exist_list:
                WidgetTip.error('{} {}'.format(ip, language_data('INPUT', 'DUPLICATE')))
                return False
            ip_exist_list.append(ip)
            return True
        login_ip_data, ip_exist_list = [], []
        for inst in self.sub_login:
            input_list = inst.get_inputs()
            if not check_input():
                inst.set_status(Global.G_TIP_FG_COLOR['FAILED'])
                return
            login_ip_data.append(input_list)
        LoginWaitTop().show()
        view_gate.try_login_data.set_data(login_ip_data)

    def try_login_result(self, data):
        """ 一键登录结果反馈回调函数 """
        index, state, info = data
        if index == 'ALL':   # 最后结果
            LoginWaitTop().finish()
            if state:
                view_gate.del_image_data.set_data(('LGN_HEAD',))
                view_gate.del_image_data.set_data(('ICO',))
                WidgetTip.info(info)
                self.destroy()
            else:
                WidgetTip.error(info)
            return state
        else:   # 单个登录结果
            instance = self.sub_login[index]
            LoginWaitTop().update(info)
            instance.set_status(Global.G_TIP_FG_COLOR[state])
            return False


class SubLogin(object):
    """ 登录子板块 """
    def __init__(self, master, prefer_ips, passwords, store):
        self.ip_en = None
        self.user_en = None
        self.upwd_en = None
        self.rpwd_en = None
        self.tip_lab = None
        self.pack(master, prefer_ips, passwords, store)
        self.see_password(False)

    def destroy(self):
        del self

    def pack(self, master, prefer_ips, passwords, store):
        def destroy():
            tip_lab.grid_remove()
            ip_en.grid_remove()
            user_en.grid_remove()
            upwd_en.grid_remove()
            rpwd_en.grid_remove()
            del_btn.grid_remove()
            store.remove(self)
            self.destroy()

        def bind_tips():
            WidgetTip.enter_tips(ip_en, language_data('IP_ADDRESS'))
            WidgetTip.enter_tips(user_en, language_data('USER_NAME'))
            WidgetTip.enter_tips(upwd_en, language_data('USER_PASSWORD'))
            WidgetTip.enter_tips(rpwd_en, language_data('ROOT_PASSWORD'))
            WidgetTip.enter_tips(del_btn, language_data('DEL_LOGIN_BAR'))

        def store_me():
            self.ip_en = ip_en
            self.user_en = user_en
            self.upwd_en = upwd_en
            self.rpwd_en = rpwd_en
            self.tip_lab = tip_lab
            store.append(self)

        def set_password():
            user_en.insert(0, passwords[0])
            upwd_en.insert(0, passwords[1])
            rpwd_en.insert(0, passwords[2])

        entry_style = {'master': master,
                       'font': (Global.G_DEFAULT_FONT, 11)}
        tip_lab = tk.Label(master, text='●', font=(Global.G_DEFAULT_FONT, 12), fg=Global.G_TIP_FG_COLOR['DEFAULT'])
        ip_en = ttk.Combobox(width=14, values=prefer_ips, **entry_style)
        if prefer_ips:
            ip_en.current(0)
        user_en = ttk.Entry(width=13, **entry_style)
        upwd_en = ttk.Entry(width=13, **entry_style)
        rpwd_en = ttk.Entry(width=13, **entry_style)
        del_btn = tk.Button(master, text='×', font=(Global.G_DEFAULT_FONT, 13, 'bold'), bd=0, command=destroy)
        index = len(store)
        grid_style = {'row': index,
                      'padx': 2,
                      'pady': 6,
                      'ipady': 2}
        tip_lab.grid(row=index, column=0)
        ip_en.grid(column=1, **grid_style)
        user_en.grid(column=2, **grid_style)
        upwd_en.grid(column=3, **grid_style)
        rpwd_en.grid(column=4, **grid_style)
        if index != 0:
            del_btn.grid(row=index, column=5)
        set_password()
        bind_tips()
        store_me()

    def get_inputs(self):
        return [self.ip_en.get(),
                self.user_en.get(),
                self.upwd_en.get(),
                self.rpwd_en.get()]

    def see_password(self, turn):
        if turn:
            self.upwd_en['show'] = ''
            self.rpwd_en['show'] = ''
        else:
            self.upwd_en['show'] = '*'
            self.rpwd_en['show'] = '*'

    def set_status(self, color):
        self.tip_lab['fg'] = color


class NewLoginTop(TopWinBase):
    """ 新建登录 """
    def pack(self, callback, defaults):
        def return_inputs(event=None):
            inputs = [en1.get(), en2.get(), en3.get(), en4.get()]
            callback(inputs)

        dft_user, dft_upwd, dft_rpwd = defaults
        self.resize(400, 200)
        tk.Label(self.master, text=language_data('NEW_LOGIN'), font=(Global.G_DEFAULT_FONT, 14)).grid(row=0, column=1)
        en1 = LabelEntry(self.master, language_data('IP_ADDRESS'), '', 1, 0, 14)
        en2 = LabelEntry(self.master, language_data('USER_NAME'), dft_user, 2, 0, 14)
        en3 = LabelEntry(self.master, language_data('USER_PASSWORD'), dft_upwd, 3, 0, 14, 32, '*')
        en4 = LabelEntry(self.master, language_data('ROOT_PASSWORD'), dft_rpwd, 4, 0, 14, 32, '*')
        en1.entry.bind('<Return>', return_inputs)
        en2.entry.bind('<Return>', return_inputs)
        en3.entry.bind('<Return>', return_inputs)
        en4.entry.bind('<Return>', return_inputs)
        ttk.Button(self.master, text=language_data('CONFIRM'), width=20, command=return_inputs
                   ).grid(row=5, column=1, pady=10)


class LoginWaitTop(TopWinBase):
    """ 等待滑块 """
    def pack(self):
        self.resize(300, 80)
        self.topping(True)
        self.label = tk.Label(self.master, font=(Global.G_DEFAULT_FONT, 11))
        self.label.pack(pady=8)
        self.progress = ttk.Progressbar(self.master, mode='indeterminate', length=250)
        self.progress.pack(ipady=3)
        self.progress.start(10)   # 设置滑块速度

    def close(self):
        pass

    def update(self, msg):
        if self.label and msg:
            self.label['text'] = msg

    def finish(self, msg=None):
        self.label.destroy()
        self.master.destroy()
        super().close()
